/********************************************************************
	Created:	2011/02/22    14:10 
	Filename: 	EntityManager.h
	Author:		falconwang
*********************************************************************/

#ifndef EntityManager_H__
#define EntityManager_H__

#include "Entity.h"

namespace Ent
{
	class EntityTemplate;

	class EntityManager
	{
	public:

		static EntityManager* Instance()
		{
			static EntityManager self;
			return &self;
		}

		~EntityManager();

		/**
		 * Initialize the entity manager, load all templates.
		 * */
		void		Initialize();

		/**
		 * Reset the system. Remove all entities.
		 * */
		void		Reset();

		/**
		 * Generate an Entity ID
		 * */
		EntID		GenerateEntityID();

		/**
		 * Create an Entity and Add the entity into this manager.
		 * */
		Entity*		CreateEntity(EntID _eID, const std::string& _eTemplate = "", const std::string& _eName = "DefEntity");

		/**
		* Create an Entity and Add the entity into this manager.
		* */
		Entity*		CreateEntity(const std::string& _eTemplate = "", const std::string& _eName = "DefEntity");

		/**
		 * Tag a entity to dead from this manager.
		 * */
		void		RemoveEntity(EntID _eId);

		/**
		 * Tag All Entity to be dead
		 * */
		void		RemoveAllEntity();

		/**
		 * Remove all dead entities
		 * */
		void		RemoveDeadEntities();

		/**
		 * Get an Entity From id
		 * */
		Entity*		GetEntity(EntID _eId);

		/**
		 * Update EntityManager
		 * */
		void		Update(float delta);

		/**
		 * Add Component Prototype
		 * */
		void		AddComponentPrototype(Component* _prototype);

		/**
		 * Remove Component Prototype
		 * */
		void		RemoveComponentPrototype(Component* _prototype);

		/**
		 * Create Component From Prototype
		 * */
		Component*	CreateComponent(const std::string& _className);

		/**
		 * Remove All Prototypes.
		 * */
		void		RemoveAllComponentPrototypes();

		/**
		 * Add an EntityTemplate to the system
		 * */
		void		AddEntityTemplate(EntityTemplate*	_template);

		/**
		 * Remove an EntityTemplate from the system
		 * */
		void		RemoveEntityTemplate(EntityTemplate*	_template);

		/**
		 * Get Entity Template From Name
		 * */
		EntityTemplate*		GetEntityTemplate(const std::string& _templateName) const;

		/**
		 * Remove All Entity Template
		 * */
		void		RemoveAllEntityTemplate();

	private:

		EntityManager();
		EntityManager(const EntityManager& _other);

	private:

		std::map<std::string, EntityTemplate*>	m_Templates;

		std::map<std::string, Component*>		m_CompPrototype;

		std::map<EntID, Entity*>				m_Entities;

		// dead entities max num to do real delete
		static const int DEAD_ENTITY_MAX_NUM =  20;
		std::list<EntID>						m_DeadEntities;

		EntID									m_eMinID; // record the min used entity id to help to gen new ids.
	};
}

#endif // EntityManager_H__